package soulkun.library.custom.view

import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import androidx.core.graphics.scale
import androidx.databinding.BindingAdapter
import soulkun.library.utils.R
import soulkun.library.utils.toPxF
import kotlin.math.max
import kotlin.math.sqrt

/**
 * 固定六边形背景的ImageView
 *
 * app:borderWidth —— 边框宽度 默认0dp
 * app:borderColor —— 边框颜色 默认白色
 */
class HexagonBackgroundImageView : androidx.appcompat.widget.AppCompatImageView {

    private val srcPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val hexagonPath = Path()
    private val borderPath = Path()
    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    private var srcWidth = 0f
    private var srcHeight = 0f
    private var hexagonPaddingHorizontal = 5.toPxF()
    private var hexagonPaddingVertical = 5.toPxF()
    private var borderWidth = 0f
    private var hexagonBackgroundColor = Color.BLACK
    private var borderColor = Color.BLACK

    private var dataBindingBackgroundColor: Int? = null
    private var dataBindingBorderColor: Int? = null

    companion object {
        //单向绑定
        @BindingAdapter("app:hexagonBackgroundColor")
        @JvmStatic
        fun setHexagonBackgroundColor(view: HexagonBackgroundImageView, params: Int) {
            if (view.dataBindingBackgroundColor != params) {
                view.dataBindingBackgroundColor = params
                view.invalidate()
            }
        }

        //单向绑定
        @BindingAdapter("app:hexagonBorderColor")
        @JvmStatic
        fun setHexagonBorderColor(view: HexagonBackgroundImageView, params: Int) {
            if (view.dataBindingBorderColor != params) {
                view.dataBindingBorderColor = params
                view.invalidate()
            }
        }

    }

    //xml文件设置
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        val typedArray =
            context.obtainStyledAttributes(attrs, R.styleable.HexagonBackgroundImageView)
        srcWidth =
            typedArray.getDimensionPixelSize(R.styleable.HexagonBackgroundImageView_srcWidth, 0)
                .toFloat()
        srcHeight =
            typedArray.getDimensionPixelSize(R.styleable.HexagonBackgroundImageView_srcHeight, 0)
                .toFloat()
        hexagonBackgroundColor = typedArray.getColor(
            R.styleable.HexagonBackgroundImageView_hexagonBackgroundColor,
            Color.BLACK
        )
        borderWidth =
            typedArray.getDimensionPixelSize(
                R.styleable.HexagonBackgroundImageView_hexagonBorderWidth,
                0
            ).toFloat()
        borderColor =
            typedArray.getColor(
                R.styleable.HexagonBackgroundImageView_hexagonBorderColor,
                Color.BLACK
            )
        typedArray.recycle()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //默认中心展示图片与六边形的宽高间距为5dp，六边形宽高比：√3:2
        val hexagonWidth = srcWidth + 2 * hexagonPaddingHorizontal
        val hexagonHeight = srcHeight + 2 * hexagonPaddingVertical
        if (hexagonWidth / sqrt(3f) > hexagonHeight / 2f) {
            setMeasuredDimension(hexagonWidth.toInt(), (hexagonWidth / sqrt(3f) * 2).toInt())
        } else {
            setMeasuredDimension((hexagonHeight / 2 * sqrt(3f)).toInt(), hexagonHeight.toInt())
        }
    }

    override fun onDraw(canvas: Canvas) {
        if (null == drawable) {
            return
        }
        canvas.clipPath(borderPath.apply {
            reset()
            moveTo(measuredWidth / 2f, 0f)
            lineTo(measuredWidth.toFloat(), measuredHeight / 4f)
            lineTo(measuredWidth.toFloat(), measuredHeight / 4 * 3f)
            lineTo(measuredWidth / 2f, measuredHeight.toFloat())
            lineTo(0f, measuredHeight / 4 * 3f)
            lineTo(0f, measuredHeight / 4f)
            close()
        })
        canvas.drawColor(dataBindingBorderColor ?: borderColor)
        canvas.drawPath(hexagonPath.apply {
            reset()
            moveTo(measuredWidth / 2f, borderWidth / sqrt(3f))
            lineTo((measuredWidth - borderWidth), measuredHeight / 4f)
            lineTo((measuredWidth - borderWidth), measuredHeight / 4 * 3f)
            lineTo(measuredWidth / 2f, measuredHeight - borderWidth / sqrt(3f))
            lineTo(borderWidth, measuredHeight / 4 * 3f)
            lineTo(borderWidth, measuredHeight / 4f)
            close()
        }, backgroundPaint.apply {
            color = dataBindingBackgroundColor ?: hexagonBackgroundColor
        })
        setBitmap(canvas)
    }

    /**
     * 设置Bitmap
     */
    private fun setBitmap(canvas: Canvas) {
        val drawable = drawable ?: return
        val bitmap = drawableToBitmap(drawable)
        canvas.drawBitmap(
            bitmap,
            null,
            Rect(
                (measuredWidth / 2 - srcWidth / 2).toInt(),
                (measuredHeight / 2 - srcHeight / 2).toInt(),
                (measuredWidth / 2 + srcWidth / 2).toInt(),
                (measuredHeight / 2 + srcHeight / 2).toInt()
            ),
            srcPaint
        )
    }

    /**
     * drawable转bitmap
     *
     * @paramdrawable
     * @return
     */
    private fun drawableToBitmap(drawable: Drawable): Bitmap {
        if (drawable is BitmapDrawable) {
            return drawable.bitmap
        }
        val w = drawable.intrinsicWidth
        val h = drawable.intrinsicHeight
        val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, w, h)
        drawable.draw(canvas)
        return bitmap.scale(srcWidth.toInt(), srcHeight.toInt(), true) //缩放
    }

}